package com.kgcx.common.controller;


import com.alibaba.fastjson.util.TypeUtils;
import com.kgcx.common.bean.RequestData;
import com.kgcx.common.utils.TokenUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

public class BaseController {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());


    /**
     * 得到RequestData
     */
    public RequestData getRequestData(HttpServletRequest request) {
        return new RequestData(request);
    }

    /**
     * 得到RequestData
     */
    public RequestData getRequestData() {
        return new RequestData(getRequest());
    }


    /**
     * @param : @return
     * @return : Map
     * @throws :
     * @Description : 得到Http消息头
     * @author : 351019187@qq.com（liusheng）
     */
    public Map getHttphead() {
        Map<String, Object> maps = new HashMap<>();
        HttpServletRequest request = getRequest();
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            maps.put(key, value);
        }
        return maps;
    }

    public String getHeader(String name) {
        return getRequest().getHeader(name);
    }

    /**
     * 获取访问者IP
     * <p>
     * 在一般情况下使用Request.getRemoteAddr()即可，但是经过nginx等反向代理软件后，这个方法会失效。
     * <p>
     * 本方法先从Header中获取X-Real-IP，如果不存在再从X-Forwarded-For获得第一个IP(用,分割)，
     * 如果还不存在则调用Request .getRemoteAddr()。
     *
     * @return
     */
    public String getIpAddr() {
        HttpServletRequest request = getRequest();
        String ip = request.getHeader("X-Real-IP");
        if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip;
        }
        ip = request.getHeader("X-Forwarded-For");
        if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个IP值，第一个为真实IP。
            int index = ip.indexOf(',');
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        } else {
            return request.getRemoteAddr();
        }
    }

    public String getToken() {
        return getHeader("token");
    }

    public Long getTokenKid() {
        String token = getHeader("token");
        if (StringUtils.isNotBlank(token)) {
            try {
                return Long.valueOf(TokenUtils.getClaims(token).getId());
            } catch (NumberFormatException e) {
                logger.error("", e);
            }
        }
        return null;
    }

    public String getTokenId() {
        String token = getHeader("token");
        if (StringUtils.isNotBlank(token)) {
            return TokenUtils.getClaims(token).getId();
        }
        return null;
    }

    public String getTokenSubject() {
        String token = getHeader("token");
        if (StringUtils.isNotBlank(token)) {
            return TokenUtils.getClaims(token).getSubject();
        }
        return null;
    }

    public boolean validateTokenId(String... ids) {
        String tokenId = this.getTokenId();
        //内部服务调用，token通过，不做权限控制
        if (TokenUtils.isInnerServer(tokenId)) {
            return true;
        }
        String tokenSubject = this.getTokenSubject();
        //管理平台用户调用，token通过，不做权限控制
        if (TokenUtils.isAdminSubject(tokenSubject)) {
            return true;
        }
        if (ArrayUtils.isNotEmpty(ids)) {
            for (String id : ids) {
                if (null != id && StringUtils.equals(tokenId, id)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 校验传入的id是否与当前tokenid相同
     * 如果不同则有可能是要查询非当前登录用户的信息，拒绝
     *
     * @param ids
     * @return
     */
    public boolean validateTokenId(Object... ids) {
        List<String> list = new ArrayList<>();
        if (ArrayUtils.isNotEmpty(ids)) {
            for (Object id : ids) {
                list.add(TypeUtils.castToString(id));
            }
        }
        return validateTokenId(list.toArray(new String[]{}));
    }


    /**
     * 得到ModelAndView
     */
    public ModelAndView getModelAndView() {
        return new ModelAndView();
    }

    /**
     * 得到request对象
     */
    protected static HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    protected static HttpServletResponse getResponse() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    }

    public void logBefore(String interfaceName) {
        logger.info("");
        logger.info("start");
        logger.info(interfaceName);
    }

    public void logBefore(Object interfaceName) {
        logBefore(String.valueOf(interfaceName));
    }

    public void logAfter(String interfaceName) {
        logger.info(interfaceName);
        logger.info("end");
        logger.info("");
    }

    public void logAfter(Object interfaceName) {
        logAfter(String.valueOf(interfaceName));
    }


    public void logError(Exception e) {
        logger.error(null, e);
    }

    public void logError(String s, Exception e) {
        logger.error(s, e);
    }

}
